<template>
    <view class="x__seats">
        <view class="x__seats__card">
            <view class="x__seats__card__bg">
                <image src="/sub_pages/movie/static/image/icon/icon_39.png" mode="aspectFill" />
            </view>
            <view class="x__seats__list">
                <view class="list__cell">
                    <view class="cell__icon"></view>
                    <view class="cell__val">可选</view>
                </view>
                <view class="list__cell">
                    <view class="cell__icon"><image src="/sub_pages/movie/static/image/icon/icon_41.png" mode="aspectFill" /></view>
                    <view class="cell__val">已售</view>
                </view>
                <view class="list__cell">
                    <view class="cell__icon"><image src="/sub_pages/movie/static/image/icon/icon_42.png" mode="aspectFill" /></view>
                    <view class="cell__val">已选</view>
                </view>
            </view>
            <view class="x__seats__tit">影院</view>
            <!-- <view class="x__seats__tit">{{ $app.movieDetail.hallName }}</view> -->
        </view>
        <view class="hei30"></view>
        <movable-area :style="'height:' + (seatRow * 40 + 350) + 'rpx;width: 100vw;top:340rpx'" class="pt-f left-0" scale-area>
            <movable-view
                :style="'width: ' + boxWidth + 'px;height:' + (seatRow * 40 + 350) + 'rpx;'"
                :inertia="true"
                :scale="true"
                :scale-min="0.4"
                :scale-max="4"
                :scale-value="scale"
                direction="all"
                @change="onMove"
                @scale="onScale"
            >
                <view style="width: 100rpx; height: 30rpx" class="m-0-a dp-f jc-c ai-c fz-20 color-999 br-5"></view>
                <!-- <view
          class="pt-f pa-v-2 b-d-l-1"
          :style="`height:${seatRow * (20 + seatSize * pxNum)}rpx;top:40rpx;width:0`"
        ></view> -->
                <view v-for="(item, index) in seatArray" :key="index" class="dp-f jc-c mt-20" :style="'width:' + boxWidth + 'px;height:' + seatSize + 'px'">
                    <view
                        v-for="(seat, col) in item"
                        :key="col"
                        class="dp-ib"
                        :style="'width:' + seatSize + 'px;height:' + seatSize + 'px;flex-shrink: 0;padding:0 2rpx'"
                        @click="handleChooseSeat(index, col)"
                    >
                        <view class="w-100 h-100" v-if="seat.type === 0">
                            <image class="w-100 h-100" v-if="seat.flag == 0" src="/sub_pages/movie/static/image/icon/icon_43.png" mode="aspectFit"></image>
                            <image class="w-100 h-100" v-if="seat.flag == 1" src="/sub_pages/movie/static/image/icon/icon_48.png" mode="aspectFit"></image>
                            <image class="w-100 h-100" v-if="seat.flag == 2" src="/sub_pages/movie/static/image/icon/icon_49.png" mode="aspectFit"></image>
                        </view>
                        <view class="w-100 h-100" v-else-if="seat.type === 1">
                            <image class="w-100 h-100" v-if="seat.flag == 0" src="/sub_pages/movie/static/image/icon/icon_42.png" mode="aspectFit"></image>
                            <image class="w-100 h-100" v-if="seat.flag == 1" src="/sub_pages/movie/static/image/icon/icon_46.png" mode="aspectFit"></image>
                            <image class="w-100 h-100" v-if="seat.flag == 2" src="/sub_pages/movie/static/image/icon/icon_47.png" mode="aspectFit"></image>
                        </view>
                        <view class="w-100 h-100" v-else-if="seat.type === 2">
                            <image class="w-100 h-100" v-if="seat.flag == 0" src="/sub_pages/movie/static/image/icon/icon_41.png" mode="aspectFit"></image>
                            <image class="w-100 h-100" v-if="seat.flag == 1" src="/sub_pages/movie/static/image/icon/icon_44.png" mode="aspectFit"></image>
                            <image class="w-100 h-100" v-if="seat.flag == 2" src="/sub_pages/movie/static/image/icon/icon_45.png" mode="aspectFit"></image>
                        </view>
                    </view>
                </view>
                <view class="pt-f bg-line br-15 over-h" :style="'left:' + (10 - moveX / scaleInit) + 'px;top:30rpx;width:30rpx;'">
                    <view class="w-100 dp-f ai-c jc-c fz-22 color-fff" :style="'height:' + seatSize + 'px;margin-top:20rpx;'" v-for="(m, mindex) in mArr" :key="mindex">
                        {{ m }}
                    </view>
                    <view :style="'height: 20rpx;'"></view>
                </view>
            </movable-view>
        </movable-area>
    </view>
</template>

<script>
export default {
    props: {
        seatData: {
            type: Array,
        },
        max: {
            type: Number,
            default: 4,
        },
    },
    data() {
        return {
            scaleMin: 0.95, //h5端为解决1无法缩小问题，设为0.95
            boxWidth: 400, //屏幕宽度px
            space: ' ', //空格
            seatArray: [], //影院座位的二维数组,-1为非座位，0为未购座位，1为已选座位(绿色),2为已购座位(红色),一维行，二维列
            seatRow: 0, //影院座位行数
            seatCol: 0, //影院座位列数
            seatSize: 0, //座位尺寸
            SelectNum: 0, //选择座位数
            moveX: 0, //水平移动偏移量
            scale: 1, //放大倍数
            scaleInit: 1,
            minRow: 0, //从第几行开始排座位
            minCol: 0, //从第几列开始排座位
            showTis: true, //显示选座提示
            seatList: [], //接口获取的原始位置
            mArr: [], //排数提示
            optArr: [], //选中的座位数组。
            isWXAPP: false,
        };
    },
    computed: {
        rpxNum() {
            return this.boxWidth / 750;
        },
        pxNum() {
            return 750 / this.boxWidth;
        },
    },
    watch: {
        seatData(newName, oldName) {
            if (newName.length > 0) {
                this.initData();
            }
        },
    },
    mounted() {
        //获取宽度
        uni.getSystemInfo({
            success: e => {
                this.boxWidth = e.screenWidth;
                //#ifdef H5
                this.scaleMin = 0.95;
                //#endif
            },
        });
    },
    methods: {
        initData: function () {
            let arr = this.seatData.map(x => {
                return {
                    RowNum: x.row,
                    ColumnNum: x.column,
                    YCoord: x.row,
                    XCoord: x.column,
                    status: x.status,
                    SeatCode: x.seatId,
                    name: x.name,
                    flag: x.flag,
                    showPrice: x?.showPrice || 0, // 官方价格/座位市场价
					salePrice: x?.salePrice || 0, // 销售价格/座位销售价
                    settlementPrice: x?.settlementPrice || 0, // 座位特惠购票结算价格
                    settlementQuickPrice: x?.settlementQuickPrice || 0, // 座位快捷出票结算价格
                };
            });

            //假数据说明：SeatCode座位编号，RowNum-行号，ColumnNum-纵号，YCoord-Y坐标，XCoord-X坐标，Status-状态
            let row = 0;
            let col = 0;
            let minCol = parseInt(arr[0].XCoord);
            let minRow = parseInt(arr[0].YCoord);
            for (let i of arr) {
                minRow = parseInt(i.YCoord) < minRow ? parseInt(i.YCoord) : minRow;
                minCol = parseInt(i.XCoord) < minCol ? parseInt(i.XCoord) : minCol;
                row = parseInt(i.YCoord) > row ? parseInt(i.YCoord) : row;
                col = parseInt(i.XCoord) > col ? parseInt(i.XCoord) : col;
            }
            this.seatList = arr;
            this.seatRow = row - minRow + 1;
            this.seatCol = col - minCol + 3;
            this.minRow = minRow;
            this.minCol = minCol - 1;

            this.initSeatArray();
        },
        //初始座位数组
        initSeatArray: function () {
            let seatArray = Array(this.seatRow)
                .fill(0)
                .map(() =>
                    Array(this.seatCol).fill({
                        type: -1,
                        SeatCode: '',
                        RowNum: '',
                        ColumnNum: '',
                        flog: 0,
                    })
                );
            this.seatArray = seatArray;
            this.seatSize = this.boxWidth > 0 ? parseInt(parseInt(this.boxWidth, 10) / (this.seatCol + 4), 10) : parseInt(parseInt(414, 10) / (this.seatCol + 4), 10);
            this.initNonSeatPlace();
        },
        //初始化是座位的地方
        initNonSeatPlace: function () {
            let seat = this.seatList.slice();
            let arr = this.seatArray.slice();
            for (let num in seat) {
                let status = 2; //-1为非座位，0为未购座位，1为已选座位(绿色),2为已购座位(红色)
                if (seat[num].status === 1) {
                    status = 0;
                } else if (seat[num].status === 2) {
                    status = 2;
                } else if (seat[num].status === -1) {
                    status = -1;
                }
                arr[parseInt(seat[num].YCoord) - this.minRow][parseInt(seat[num].XCoord) - this.minCol] = {
                    type: status,
                    SeatCode: seat[num].SeatCode,
                    RowNum: seat[num].RowNum,
                    ColumnNum: seat[num].ColumnNum,
                    Name: seat[num].name,
                    flag: seat[num].flag, // 1左情侣座 2右情侣座
                    showPrice: seat[num]?.showPrice || 0, // 官方价格/座位市场价
					salePrice: seat[num]?.salePrice || 0, // 销售价格/座位销售价
                    settlementPrice: seat[num]?.settlementPrice || 0, // 座位特惠购票结算价格
                    settlementQuickPrice: seat[num]?.settlementQuickPrice || 0, // 座位快捷出票结算价格
                };
            }
            this.seatArray = arr.slice();
            let mArr = [];
            let index = 1;
            for (let i in arr) {
                let m = '';
                for (let n of arr[i]) {
                    if (n.SeatCode) {
                        m = n.RowNum;
                    }
                }
                if (m || m === 0) {
                    mArr.push(index++);
                } else {
                    mArr.push('');
                }
            }
            this.mArr = mArr;
        },
        //放大缩小事件
        onScale: function (e) {
            this.showTis = false;
            // this.moveX=-e.detail.x
            this.$nextTick(() => {
                let w = this.boxWidth * 0.5;
                let s = 1 - e.detail.scale;
                this.moveX = w * s;
                // this.scale = e.detail.scale;
                this.scaleInit = e.detail.scale;
                if (s > 0 || s === 0) {
                    this.showTis = true;
                }
            });
        },
        //移动事件
        onMove: function (e) {
            this.showTis = false;
            this.moveX = e.detail.x;
        },
        //重置座位
        resetSeat: function () {
            this.SelectNum = 0;
            this.optArr = [];
            //将所有已选座位的值变为0
            let oldArray = this.seatArray.slice();
            for (let i = 0; i < this.seatRow; i++) {
                for (let j = 0; j < this.seatCol; j++) {
                    if (oldArray[i][j].type === 1) {
                        oldArray[i][j].type = 0;
                    }
                }
            }
            this.seatArray = oldArray;
        },
        //选定且购买座位
        buySeat: function () {
            if (this.SelectNum === 0) return;
            // let oldArray = [];
            // for (let i = 0; i < this.seatRow; i++) {
            // 	for (let j = 0; j < this.seatCol; j++) {
            // 		if (this.seatArray[i][j].type === 1) {
            // 			oldArray.push(this.seatArray[i][j])
            // 		}
            // 	}
            // }

            this.$emit('confirm', this.optArr);
        },
        //处理座位选择逻辑
        handleChooseSeat: function (row, col) {
            let seatValue = this.seatArray[row][col].type;
            let newArray = this.seatArray;
            //如果是已购座位，直接返回
            if (seatValue === 2 || seatValue === -1) return;
            //如果是已选座位点击后变未选
            if (seatValue === 1) {
                //处理情侣座 1左情侣座 2右情侣座 0普通座位 选择情侣座时，另一半也要取消选中
                if (newArray[row][col].flag === 1) {
                    newArray[row][col + 1].rowIndex = row;
                    newArray[row][col + 1].colIndex = col;
                    newArray[row][col + 1].type = 0;
                    this.SelectNum--;
                    this.getOptArr(newArray[row][col + 1], 0);
                } else if (newArray[row][col].flag === 2) {
                    newArray[row][col - 1].type = 0;
                    newArray[row][col - 1].rowIndex = row;
                    newArray[row][col - 1].colIndex = col;
                    this.SelectNum--;
                    this.getOptArr(newArray[row][col - 1], 0);
                }
                newArray[row][col].rowIndex = row;
                newArray[row][col].colIndex = col;
                newArray[row][col].type = 0;
                this.SelectNum--;
                this.getOptArr(newArray[row][col], 0);
            } else if (seatValue === 0) {
                if (this.SelectNum >= this.max) {
                    return uni.showToast({
                        title: '一次最多选择' + this.max + '张',
                        icon: 'none',
                    });
                }
                //处理情侣座 1左情侣座 2右情侣座 0普通座位 选择情侣座时，另一半也要选中
                if (newArray[row][col].flag === 1) {
                    if (newArray[row][col + 1].type === 0) {
                        newArray[row][col + 1].type = 1;
                        newArray[row][col + 1].rowIndex = row;
                        newArray[row][col + 1].colIndex = col;
                        this.SelectNum++;
                        this.getOptArr(newArray[row][col + 1], 1);
                    }
                } else if (newArray[row][col].flag === 2) {
                    if (newArray[row][col - 1].type === 0) {
                        newArray[row][col - 1].type = 1;
                        newArray[row][col - 1].rowIndex = row;
                        newArray[row][col - 1].colIndex = col;
                        this.SelectNum++;
                        this.getOptArr(newArray[row][col - 1], 1);
                    }
                }
                newArray[row][col].rowIndex = row;
                newArray[row][col].colIndex = col;
                newArray[row][col].type = 1;
                this.SelectNum++;
                this.getOptArr(newArray[row][col], 1);
            }
            //必须整体更新二维数组，Vue无法检测到数组某一项更新,必须slice复制一个数组才行
            this.seatArray = newArray.slice();
        },
        //处理已选座位数组
        getOptArr: function (item, type) {
            let optArr = this.optArr;
            if (type === 1) {
                optArr.push(item);
            } else if (type === 0) {
                let arr = [];
                optArr.forEach(v => {
                    if (v.SeatCode !== item.SeatCode) {
                        arr.push(v);
                    }
                });
                optArr = arr;
            }
            this.optArr = optArr.slice();
            this.$emit('confirm', this.optArr);
        },
        //推荐选座,参数是推荐座位数目，
        smartChoose: function (num) {
            // 先重置
            this.resetSeat();
            //找到影院座位水平垂直中间位置的后一排
            let rowStart = parseInt((this.seatRow - 1) / 2, 10) + 1;
            //先从中间排往后排搜索
            let backResult = this.searchSeatByDirection(rowStart, this.seatRow - 1, num);
            if (backResult.length > 0) {
                this.chooseSeat(backResult);
                this.SelectNum += num;
                return;
            }
            //再从中间排往前排搜索
            let forwardResult = this.searchSeatByDirection(rowStart - 1, 0, num);
            if (forwardResult.length > 0) {
                this.chooseSeat(forwardResult);
                this.SelectNum += num;
                return;
            }
            //提示用户无合法位置可选
            // #ifdef H5
            this.$toast('无合法位置可选!');
            // alert()
            // #endif
        },

        //搜索函数,参数:fromRow起始行，toRow终止行,num推荐座位数
        searchSeatByDirection: function (fromRow, toRow, num) {
            let currentDirectionSearchResult = [];

            let largeRow = fromRow > toRow ? fromRow : toRow,
                smallRow = fromRow > toRow ? toRow : fromRow;

            for (let i = smallRow; i <= largeRow; i++) {
                //每一排的搜索,找出该排里中轴线最近的一组座位
                let tempRowResult = [],
                    minDistanceToMidLine = Infinity;
                for (let j = 0; j <= this.seatCol - num; j++) {
                    //如果有合法位置
                    if (this.checkRowSeatContinusAndEmpty(i, j, j + num - 1)) {
                        //计算该组位置距离中轴线的距离:该组位置的中间位置到中轴线的距离
                        let resultMidPos = parseInt(j + num / 2, 10);
                        let distance = Math.abs(parseInt(this.seatCol / 2) - resultMidPos);
                        //如果距离较短则更新
                        if (distance < minDistanceToMidLine) {
                            minDistanceToMidLine = distance;
                            //该行的最终结果
                            tempRowResult = this.generateRowResult(i, j, j + num - 1);
                        }
                    }
                }
                //保存该行的最终结果
                currentDirectionSearchResult.push({
                    result: tempRowResult,
                    offset: minDistanceToMidLine,
                });
            }

            //处理后排的搜索结果:找到距离中轴线最短的一个
            //注意这里的逻辑需要区分前后排，对于后排是从前往后，前排则是从后往前找
            let isBackDir = fromRow < toRow;
            let finalReuslt = [],
                minDistanceToMid = Infinity;
            if (isBackDir) {
                //后排情况,从前往后
                currentDirectionSearchResult.forEach(item => {
                    if (item.offset < minDistanceToMid) {
                        finalReuslt = item.result;
                        minDistanceToMid = item.offset;
                    }
                });
            } else {
                //前排情况，从后往前找
                currentDirectionSearchResult.reverse().forEach(item => {
                    if (item.offset < minDistanceToMid) {
                        finalReuslt = item.result;
                        minDistanceToMid = item.offset;
                    }
                });
            }

            //直接返回结果
            return finalReuslt;
        },

        /*辅助函数，判断每一行座位从i列到j列是否全部空余且连续
         *
         */
        checkRowSeatContinusAndEmpty: function (rowNum, startPos, endPos) {
            let isValid = true;
            for (let i = startPos; i <= endPos; i++) {
                if (this.seatArray[rowNum][i].type !== 0) {
                    isValid = false;
                    break;
                }
            }
            return isValid;
        },
        //辅助函数：返回每一行的某个合理位置的座位数组
        generateRowResult: function (row, startPos, endPos) {
            let result = [];
            for (let i = startPos; i <= endPos; i++) {
                result.push([row, i]);
            }
            return result;
        },
        //辅助函数:智能推荐的选座操作
        chooseSeat: function (result) {
            let opt = this.optArr;
            let oldArray = this.seatArray.slice();
            for (let i = 0; i < result.length; i++) {
                //选定座位
                oldArray[result[i][0]][result[i][1]].rowIndex = result[i][0];
                oldArray[result[i][0]][result[i][1]].colIndex = result[i][1];
                oldArray[result[i][0]][result[i][1]].type = 1;
                this.optArr.push(oldArray[result[i][0]][result[i][1]]);
            }
            this.seatArray = oldArray;
        },
    },
};
</script>

<style lang="scss" scoped>
.x__seats {
    .x__seats__card {
        display: flex;
        align-items: center;
        flex-direction: column;
        justify-content: space-between;
        position: relative;
        width: 100vw;
        height: 175rpx;
        z-index: 3;

        .x__seats__card__bg {
            position: absolute;
            top: 0;
            left: -30rpx;
            right: -30rpx;
            height: 175rpx;
            background: #f6f6f6;
            z-index: -1;
            image {
                width: 100%;
                height: 100%;
            }
        }
        .x__seats__tit {
            padding: 0 10rpx;
            min-width: 330rpx;
            height: 60rpx;
            background: #f4f4f4;
            opacity: 1;
            border: 1px solid #e7e7e7;

            font-size: 23rpx;
            font-weight: normal;
            color: #999999;
            display: flex;
            justify-content: center;
            align-items: center;
            margin-bottom: -9rpx;
        }
        .x__seats__list {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 40rpx;
            margin-top: 38rpx;
            .list__cell {
                display: flex;
                align-items: center;
                gap: 9rpx;
            }
            .cell__icon {
                width: 40rpx;
                height: 40rpx;
                background: #ffffff;
                border-radius: 7rpx;
                opacity: 1;
                border: 1px solid #eaeaea;

                image {
                    width: 100%;
                    height: 100%;
                }
            }
            .cell__val {
                font-size: 24rpx;
                font-weight: normal;
                color: #333333;
            }
        }
    }
}

.p-all-10 {
    padding: 10rpx;
}
.ml-10 {
    margin-left: 10rpx;
}

.m-0-10 {
    margin: 0 10rpx;
}

.bg-unbtn {
    background-color: #f9abb3;
}

.bg-red-1 {
    background-color: #f45664;
}

.br-10 {
    border-radius: 10rpx;
}

.ml-20 {
    margin-left: 20rpx;
}

.mb-20 {
    margin-bottom: 20rpx;
}

.p-all-32 {
    padding: 32rpx;
}

.fd-cr {
    flex-direction: column-reverse;
    /* 主轴方向从下到上,默认从左到右 */
}

.bottom-bar {
    bottom: var(--window-bottom);
}

.color-fff {
    color: #fff;
}

.br-15 {
    border-radius: 15rpx;
}

.over-h {
    overflow: hidden;
}

.dp-ib {
    display: inline-block;
}

.mt-20 {
    margin-top: 20rpx;
}

.ml-10 {
    margin-left: 10rpx;
}
.mr-10 {
    margin-right: 10rpx;
}

.pa-v-2 {
    /* 定位垂直对齐 */
    left: 50%;
    transform: translateX(-50%);
}

.b-d-1 {
    border: 1px dashed #e5e5e5;
}

.b-d-l-1 {
    border-left: 1px dashed #e5e5e5;
}

.w-100 {
    width: 100%;
}

.h-100 {
    height: 100%;
}

.bg-f1 {
    background-color: #f1f1f1;
}

.h-100vh {
    height: 100vh;
}

.pt-f {
    position: fixed;
}

.left-0 {
    left: 0;
}

.p-0-32 {
    padding: 0 32rpx;
}

.pt-20 {
    padding-top: 20rpx;
}

.bg-white {
    background-color: #fff;
}

.z1000 {
    z-index: 1000;
}

.fz-34 {
    font-size: 34rpx;
}

.fw-b {
    font-weight: bold;
}

.mt-10 {
    margin-top: 10rpx;
}

.fz-28 {
    font-size: 28rpx;
}

.color-666 {
    color: #666666;
}

.dp-f {
    display: flex;
}

.jc-c {
    justify-content: center;
}

.gap-20 {
    gap: 0 20rpx;
}

.ai-c {
    align-items: center;
}

.fz-22 {
    font-size: 22rpx;
}

.color-333 {
    color: #333333;
}

.m-0-a {
    margin: 0 auto;
}

.mt-48 {
    margin-top: 48rpx;
}

.fz-20 {
    font-size: 20rpx;
}

.color-999 {
    color: #999999;
}

.b-1 {
    border: 1px solid #cccccc;
}

.br-5 {
    border-radius: 5rpx;
}

.Stage {
    background-color: #dddddd;
    width: 380rpx;
    height: 34rpx;
    transform: perspective(34rpx) rotateX(-10deg);
    margin: 0 auto;
}

.bg-line {
    background-color: rgba(0, 0, 0, 0.3);
}
</style>
